using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using log4net;
using Shc.Sql;

namespace CLZ.Common
{
    public class DbManager : MSSql2005EntityManager
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(DbManager));
        private DbManager(string connectionString)
            : base(connectionString)
        {

        }

        static DbManager m_current;

        public static DbManager Current
        {
            get
            {
                if (m_current == null)
                {
                    string cnStr = Config.ConnectionString;
                    m_current = new DbManager(cnStr);
                }
                return m_current;
            }
        }

        public new DbSession OpenSession()
        {
            DbSession ss = CreateSession();
            ss.OnError += new EventHandler<DbSessionErrorEventArgs>(ss_OnError);
#if DEBUG
            ss.OnBeforeExecute += new EventHandler<DbSessionSqlEventArgs>(ss_OnBeforeExecute);
            ss.OnBeforeGetCellData += new EventHandler<DbSessionSqlEventArgs>(ss_OnBeforeGetCellData);
            ss.OnBeforeGetRowData += new EventHandler<DbSessionSqlEventArgs>(ss_OnBeforeGetRowData);
            ss.OnBeforeGetListData += new EventHandler<DbSessionSqlEventArgs>(ss_OnBeforeGetListData);
#endif
            return ss.OpenSession() ? ss : null;
        }

        /// <summary>
        /// When get list data
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ss_OnBeforeGetListData(object sender, DbSessionSqlEventArgs e)
        {
            LogSql(e);   
        }

        /// <summary>
        /// When get row data
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ss_OnBeforeGetRowData(object sender, DbSessionSqlEventArgs e)
        {
            LogSql(e); 
        }

        /// <summary>
        /// When get cell data
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ss_OnBeforeGetCellData(object sender, DbSessionSqlEventArgs e)
        {
            LogSql(e); 
        }

        /// <summary>
        /// When Execute Sql
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ss_OnBeforeExecute(object sender, DbSessionSqlEventArgs e)
        {
            LogSql(e); 
        }

        static void LogSql(DbSessionSqlEventArgs e)
        {
            try
            {
                string sqlInfo = DbSessionDebuger.GetSqlExecuteInfo(e.SqlExecute, e.SqlParams);

                string sqlLogsFolder = HttpContext.Current.Server.MapPath("~/log/sql/");
                System.IO.Directory.CreateDirectory(sqlLogsFolder);
                string sqlLogFile = sqlLogsFolder + (sqlLogsFolder.Substring(sqlLogsFolder.Length - 1, 1).Equals("\\") ? "" : "\\")
                                + DateTime.Now.ToString("yyyyMMdd") + ".txt";
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("Time:" + DateTime.Now.ToString());
                sb.AppendLine(sqlInfo);
                sb.AppendLine("");
                System.IO.File.AppendAllText(sqlLogFile, sb.ToString(), Encoding.UTF8);
            }
            catch (System.Exception ex)
            {
            	
            }
        }

        public static void LogErr(string errInfo, bool isStop)
        {
            try
            {
                log.Error(errInfo);
            }
            catch (System.Exception ex)
            {
#if DEBUG
                throw ex;
#endif
            }
        }

        public static void LogErr(string errInfo)
        {
            LogErr(errInfo, true);
        }

        public static void LogErr(Exception ex, bool isStop)
        {
            LogErr(Shc.Sql.DbSessionDebuger.GetDebugInfo(ex));
        }

        /// <summary>
        /// Error Handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ss_OnError(object sender, DbSessionErrorEventArgs e)
        {
            LogErr(e.DebugInfo);
            WebHelper.EndPage500();
        }

        #region Query
        public T FindPK<T>(object[] primaryKeyValues) where T : IDbSessionEntity, new()
        {
            using(DbSession ss = OpenSession())
            {
                return base.FindPK<T>(ss, primaryKeyValues);
            }
        }

        public T Find<T>(params Criterion[] criterions) where T : IDbSessionEntity, new()
        {
            using(DbSession ss = OpenSession())
            {
                return base.Find<T>(ss, criterions);
            }
        }

        public long GetPagingRecords(string table,  params Criterion[] criterions)
        {
            using (DbSession ss = OpenSession())
            {
                return base.GetPagingRecords(ss, table, criterions);
            }
        }

        public bool Query<T>(IList<T> list, int curPage, int pageSize, Sql[] orders, params Criterion[] criterions)
            where T : IDbSessionEntity, new()
        {
            using (DbSession ss = OpenSession())
            {
                return base.Query<T>(ss, list, curPage, pageSize, orders, criterions);
            }
        }

        public bool Query<T>(IList<T> list, Sql[] orders, params Criterion[] criterions)
            where T : IDbSessionEntity, new()
        {
            using (DbSession ss = OpenSession())
            {
                return base.Query<T>(ss, list, orders, criterions);
            }
        }
        #endregion
    }
}